home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / 131_01.zip / AEXP.C < prev    next >
Text File  |  1993-06-05  |  5KB  |  255 lines

  1. /*
  2.     ************************************************************
  3.             ACRL Expression evaluator
  4.     ************************************************************
  5.  
  6.     W. Lemiszki                      9 Jan 1982
  7.  
  8.     Filename: aexp.c                 BDS C v1.50
  9. */
  10.  
  11. #include "acrl.h"
  12.  
  13. /*
  14.     Scans the next expression from the input line and returns its
  15.     value.  The global 'xrel' is set TRUE if the expression is
  16.     relocatable.  This routine (and expr(), and operand()) assumes
  17.     that the first token has already been scanned.
  18.  
  19.     expr() takes a precedence argument and scans recursively until
  20.     it finds an operator that has lower precedence.
  21.  
  22.     operand() scans operands and handles unary operators and
  23.     parenthesized sub expressions.
  24. */
  25.  
  26. int expression()
  27. {
  28.     return (expr(0));            /* start with precedence 0 */
  29. }
  30.  
  31.  
  32. int expr(lprec)
  33. byte lprec;
  34. {
  35.     byte op, rprec, urel;
  36.     int u, v;
  37.  
  38.     u = operand();                /* scan an operand */
  39.     while (class == OPERATOR  &&  (rprec = prec(type)) > lprec)
  40.         {
  41.         op = type;                /* save operator type */
  42.         urel = xrel;            /* save reloc attr */
  43.         scan();                /* next token */
  44.         v = expr(rprec);            /* get right 'operand' */
  45.         xrel = opreloc(op, urel, xrel);    /* compute reloc atribute */
  46.         u = operate(op, u, v);        /* perform operator */
  47.         }
  48.     return (u);
  49. }
  50.  
  51.  
  52.  
  53.  
  54. /*
  55.  *    Return the precedence of an operator
  56.  *    ------------------------------------
  57.  */
  58. byte prec(op)
  59. byte op;
  60. {
  61.     switch (op)
  62.         {
  63.         case '*':
  64.         case '/':
  65.         case opMOD:
  66.         case opSHL:
  67.         case opSHR:
  68.         return (6);
  69.  
  70.         case '+':
  71.         case '-':
  72.         return (4);
  73.  
  74.         case opAND:
  75.         return (2);
  76.  
  77.         default:
  78.         return (1);
  79.         }
  80. }
  81.  
  82.  
  83.  
  84. /*
  85.  *    Compute the relocatability of an operation
  86.  *    ------------------------------------------
  87.  */
  88. int opreloc(op, urel, vrel)
  89. byte op;                /* the operator */
  90. byte urel;                /* reloc. atr. of left operand */
  91. byte vrel;                /* reloc. atr. of right operand */
  92. {
  93.     if (!urel && !vrel)            /* both absolute */
  94.         return FALSE;
  95.  
  96.     if (op == '-' && urel && vrel)        /* rel - rel */
  97.         return FALSE;
  98.  
  99.     if (op == '+' && !urel && vrel)        /* abs + rel */
  100.         return TRUE;
  101.  
  102.     if ((op == '+' || op == '-') && urel && !vrel)
  103.         return TRUE;            /* rel +/- abs */
  104.  
  105.     error('T');                /* all others illegal */
  106.     return FALSE;
  107. }
  108.  
  109.  
  110.  
  111.  
  112. /*
  113.  *    Perform an operator function
  114.  *    ----------------------------
  115.  */
  116. int operate(op, u, v)
  117. byte op;                    /* the operator */
  118. int u;                        /* left operand */
  119. int v;                        /* right operand */
  120. {
  121.     switch (op)
  122.         {
  123.         case '+':
  124.         return (u + v);
  125.  
  126.         case '-':
  127.         return (u - v);
  128.  
  129.         case '*':
  130.         return (u * v);
  131.  
  132.         case '/':
  133.         return (u / v);
  134.  
  135.         case opAND:
  136.         return (u & v);
  137.  
  138.         case opOR:
  139.         return (u | v);
  140.  
  141.         case opXOR:
  142.         return (u ^ v);
  143.  
  144.         case opMOD:
  145.         return (u % v);
  146.  
  147.         case opSHR:
  148.         return (u >> v);
  149.  
  150.         case opSHL:
  151.         return (u << v);
  152.         }
  153. }
  154.  
  155.  
  156.  
  157.  
  158. /*
  159.  *    Operand Scanning
  160.  *    ----------------
  161.  */
  162. int operand()
  163. {
  164.     int v;
  165.  
  166.     if (type == '-')            /* if '-' operator... */
  167.         class = OPERAND;        /* make it unary minus */
  168.  
  169.     if (class == IDENT)            /* if identifier... */
  170.         {
  171.         if (type == idUND)        /* check for errors */
  172.             error ('U');        /* undefined */
  173.         if (type == idFUNC)
  174.             error ('X');        /* external error */
  175.         class = OPERAND;        /* then make it ok */
  176.         type = NUMBER;
  177.         }
  178.  
  179.     if (class == STRING && tokbuf[1] == EOS)    /* if 1 char string... */
  180.         {
  181.         value = *tokbuf;        /* use its ASCII code */
  182.         class = OPERAND;
  183.         type = NUMBER;
  184.         }
  185.  
  186.     if (class != OPERAND)            /* if not an operand... */
  187.         {
  188.         error('E');            /* expression error */
  189.         return (0);
  190.         }
  191.  
  192.     switch (type)
  193.         {
  194.         case '-':                /* unary - */
  195.         v = -unary();
  196.         break;
  197.  
  198.         case opNOT:                /* unary NOT */
  199.         v = ~unary();
  200.         break;
  201.  
  202.         case opHIGH:            /* unary HIGH */
  203.         v = unary() >> 8;
  204.         break;
  205.  
  206.         case opLOW:                /* unary LOW */
  207.         v = unary() & 0xFF;
  208.         break;
  209.  
  210.  
  211.  
  212.         case '$':                /* location counter */
  213.         if (!infunc)
  214.             error('E');            /* expression error */
  215.         v = floc;
  216.         xrel = TRUE;
  217.         scan();
  218.         break;
  219.  
  220.         case '(':                /* subexpression */
  221.         scan();
  222.         v = expression();
  223.         if (type != ')')
  224.             error('B');            /* balance error */
  225.         scan();
  226.         break;
  227.  
  228.         default:
  229.         v = value;            /* current token params */
  230.         xrel = reloc;
  231.         scan();
  232.         }
  233.     return (v);
  234. }
  235.  
  236.  
  237.  
  238. /* Prepare for unary operation */
  239. int unary()
  240. {
  241.     int v;
  242.  
  243.     scan();
  244.     v = operand();
  245.     if (xrel)            /* unarys illegal on relocs */
  246.         {
  247.         error('T');        /* type error */
  248.         xrel = 0;
  249.         }
  250.     return (v);
  251. }
  252.  
  253.  
  254. /*EOF*/
  255.